use actix_web::{HttpRequest, web};

use common::error::MyError;
use common::header::Authorization;
use common::page::{BasePage, PageResult};

use crate::manager::base::BaseManager;

/// 抽象增删改查服务层
/// Unlike [`ID`] ID 实体模型id类型
/// Unlike [`ENTITY`] 实体模型 当前版本作为接口返回值
/// Unlike [`PAGE`] 分页参数
/// Unlike [`CREATE`] 添加数据的入参对象
/// Unlike [`UPDATE`] UPDATE 更新数据的入参对象
/// Unlike [`MANAGER`] 数据库实际操作对象 需要实现 [`BaseManager`]
#[allow(async_fn_in_trait)]
pub trait BaseService<ID, ENTITY, PAGE, CREATE, UPDATE, MANAGER>
where
    PAGE: BasePage,
    MANAGER: BaseManager<ID, ENTITY, PAGE, CREATE, UPDATE>,
{
    async fn list(
        _req: &HttpRequest,
        _authorization: web::Header<Authorization>,
    ) -> Result<Vec<ENTITY>, MyError> {
        Ok(MANAGER::list().await?)
    }

    async fn page(
        page: PAGE,
        _req: &HttpRequest,
        _authorization: web::Header<Authorization>,
    ) -> Result<PageResult<ENTITY>, MyError> {
        Ok(MANAGER::page(page).await?)
    }

    async fn info(
        id: ID,
        _req: &HttpRequest,
        _authorization: web::Header<Authorization>,
    ) -> Result<ENTITY, MyError> {
        let data = MANAGER::info(id)
            .await?
            .ok_or(MyError::ServerError("data does not exist".to_string()))?;
        Ok(data)
    }

    async fn add(
        form: CREATE,
        _req: &HttpRequest,
        _authorization: web::Header<Authorization>,
    ) -> Result<ID, MyError> {
        Ok(MANAGER::add(form).await?)
    }

    async fn update(
        form: UPDATE,
        _req: &HttpRequest,
        _authorization: web::Header<Authorization>,
    ) -> Result<ID, MyError> {
        Ok(MANAGER::update(form).await?)
    }

    async fn delete(
        id: ID,
        _req: &HttpRequest,
        _authorization: web::Header<Authorization>,
    ) -> Result<bool, MyError> {
        Ok(MANAGER::delete(id).await?)
    }
}
